package com.miaoxie.dao;

import com.miaoxie.domain.MyEntity;
import com.sun.jndi.toolkit.dir.SearchFilter;
import javafx.concurrent.Task;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.JpaEntityInformationSupport;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.util.StringUtils;

import javax.persistence.EntityManager;
import java.io.Serializable;
import java.util.Map;
import java.util.UUID;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: miaoxie
 * Date: 2018-05-16
 * Time: 上午8:58
 */
@NoRepositoryBean
public  class BaseDaoImpl<T, ID extends Serializable> extends SimpleJpaRepository<T,ID> implements BaseDao<T,ID>{

    JpaEntityInformation<T, ?> entityInformation;
    /**
     * Creates a new {@link SimpleJpaRepository} to manage objects of the given {@link JpaEntityInformation}.
     *
     * @param entityInformation must not be {@literal null}.
     * @param entityManager     must not be {@literal null}.
     */
    public BaseDaoImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
    }

    /**
     * Creates a new {@link SimpleJpaRepository} to manage objects of the given domain type.
     *
     * @param domainClass must not be {@literal null}.
     * @param em          must not be {@literal null}.
     */
    public BaseDaoImpl(Class<T> domainClass, EntityManager em) {
        super(domainClass, em);
        this.entityInformation = JpaEntityInformationSupport.getEntityInformation(domainClass,em);

    }

    /**
     * Creates a new {@link SimpleJpaRepository} to manage objects of the given {@link JpaEntityInformation}.
     *
     * @param entityInformation must not be {@literal null}.
     * @param entityManager     must not be {@literal null}.
//     */
//    public BaseDaoImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
//        super(entityInformation, entityManager);
//    }
//
//    /**
//     * Creates a new {@link SimpleJpaRepository} to manage objects of the given domain type.
//     *
//     * @param domainClass must not be {@literal null}.
//     * @param em          must not be {@literal null}.
//     */
//    public BaseDaoImpl(Class<T> domainClass, EntityManager em) {
//        super(domainClass, em);
//    }

    public <S extends T> S save(S entity){

        if (this.entityInformation.isNew(entity)){
            if (entity instanceof MyEntity){
                MyEntity myEntity = get(entity,MyEntity.class);
                myEntity.setId(getUUID());
            }
        }


        return super.save(entity);
    }
    /**
     * 自动生成32位的UUid，对应数据库的主键id进行插入用。
     * @return
     */
    private static String getUUID() {
        /*UUID uuid = UUID.randomUUID();
        String str = uuid.toString();
        // 去掉"-"符号
        String temp = str.substring(0, 8) + str.substring(9, 13)
                + str.substring(14, 18) + str.substring(19, 23)
                + str.substring(24);
        return temp;*/

        return UUID.randomUUID().toString().replace("-", "");
    }
    public static <T> T get(Object o,Class<T> clazz){
        if(clazz!=null){
            if(clazz.isInstance(o))
                return clazz.cast(o);
            else
                throw new RuntimeException(o +" is not a "+clazz.getName());
        }
        return null;
    }

    public static <T> T get(Object o,T t){
        Class<T> clazz=(Class<T>) t.getClass();
        if(clazz!=null){
            if(clazz.isInstance(o))
                return clazz.cast(o);
            else
                throw new RuntimeException(o +" is not a "+clazz.getName());
        }
        return null;
    }

}
